// 记载带有token的vuex容器模块
import store from '@/store'
// 封装 axios 请求模块
import axios from 'axios'

import JSONBig from 'json-bigint'

// 导入路由管理器
import router from '@/router'

// 创建 axios实例，并设置配置项
// 原因：未来复杂项目中，接口可能部署在不同地址的服务器上，所以 需要创建设置不同基地址的axios对象
const request = axios.create({
  baseURL: 'http://toutiao-app.itheima.net', // 基础路径
  // 自定义后端返回的原始数据
  // data: 后端返回的原始数据，说白了就是 JSON 格式的字符串
  // transformResponse 允许自定义原始的响应数据（字符串）
  transformResponse: [function (data) {
    try {
      // 如果转换成功则返回转换的数据结果
      return JSONBig.parse(data)
    } catch (err) {
      // 如果转换失败，则包装为统一数据格式并返回
      return data
    }
    // axios 默认会在内部这样来处理后端返回的数据
    // return JSON.parse(data)
  }]
})

// 请求拦截器--设置统一的headers-----------------------
request.interceptors.request.use(function (config) {
  // 请求发起会经过这里
  // config：本次请求的请求配置对象
  const { user } = store.state// 获取仓库中的用户数据
  // a.先判断 有没有token（如登录时，就没有token，就不需要添加token）
  // b.且判断 请求头有没有Authorization这个属性，如果有了就不要再重新设置
  //   获取新的token时，需要携带refresh_token请求，而不是token
  if (user && user.token && !config.headers.Authorization) {
    // 给请求报文头添加token
    config.headers.Authorization = `Bearer ${user.token}`
  }
  // 注意：这里务必要返回配置对象，否则请求就停在这里出不去了
  return config// 返回修改后的axios配置对象
}, function (error) {
//  如果请求出错了（还没有发出去）会经过这里
  return Promise.reject(error)
})

// 设置响应拦截器---------------------------------------------------------------
request.interceptors.response.use(
  // 响应成功进入第1个函数
  // 该函数的参数是响应对象
  config => {
    // console.log('响应拦截器:', config)
    return config
  },
  // 响应失败进入第2个函数，该函数的参数是错误对象
  err => {
    // 如果响应码是 401 ，则请求获取新的 token
    // 响应拦截器中的 error 就是那个响应的错误对象
    // console.dir(err)

    if (err.response && err.response.status === 401) {
      // 校验是否有 refresh_token
      const { user } = store.state
      if (!user || !user.refresh_token) {
        // a. 如果没有就 跳转到登录页面，重新登录
        return router.push('/login')
      }
      // b. 如果有refresh_token，则请求获取新的 token
      getNewToken(user)
    }
  }
)

//  请求新的token
async function getNewToken (user) {
  // 发送请求新的 token的请求
  const { data } = await request({
    url: '/v1_0/authorizations',
    method: 'PUT',
    headers: {
      Authorization: `Bearer ${user.refresh_token}`
    }
  })
  // 判断请求是否成功
  if (data.message === 'OK') {
    // 拿到新的token ，存到store和本地里
    const newToken = data.data.token
    // 调用store用的方法，更新token
    store.commit('updateToken', newToken)
    // 再手动 重新刷新当前页面
    window.location.reload()
  }
}

export default request
